from typing import List, Optional, Tuple
from app.utils.request import RequestHandler
from app.core.crud import CRUDBase
from app.models.system.blog import Blog
from app.schemas.system.blog import BlogCreate, BlogUpdate,BlogResponse
from app.services.system.blog import blog_service
from app.schemas.base.error_code import *
from app.core.exceptions import BusinessError
from app.utils.app_log import logger
from tortoise.expressions import Q

class BlogController():
    async def blog_list(self, page: int, page_size: int, q: Q) -> Tuple[int, List[dict]]:
        """获取博客列表"""
        try:
            total, blog_objs = await blog_service.list(page=page, page_size=page_size, search=q)
            data = [await obj.to_dict() for obj in blog_objs]
            return total, data
        except Exception as e:
            raise BusinessError(RESOURCE_ACCESS_DENIED, details=f"获取博客列表出错：{str(e)}")

    async def get_blog_info(self, blog_id: int, user_id: int) -> dict:
        """获取博客详情"""
        try:
            blog_obj = await blog_service.get_blog_by_user(blog_id, user_id)
            if not blog_obj:
                raise BusinessError(RESOURCE_NOT_FOUND.format(resource="博客"), details="博客不存在")
            blog_dict = await blog_obj.to_dict()
            # logger.info(f"获取博客详情：{blog_dict}")
            if blog_obj.user:
                blog_dict['username'] = blog_obj.user.username
            return blog_dict
        except Exception as e:
            raise BusinessError(RESOURCE_NOT_FOUND.format(resource="博客"), details=f"博客不存在：{str(e)}")

    async def remove_blog(self, blog_id: int, user_id: int) -> bool:
        """删除博客"""
        try:
            blog_obj = await blog_service.get_blog_by_user(blog_id, user_id)
            if not blog_obj:
                raise BusinessError(RESOURCE_NOT_FOUND.format(resource="博客"), details="博客不存在")
            await blog_service.remove(blog_id)
            return True
        except Exception as e:
            raise BusinessError(RESOURCE_DELETE_FAILED.format(resource="博客"), details=f"删除博客失败 {str(e)}")

    async def create_blog(self, blog_in: BlogCreate) -> Blog:
        """创建博客"""
        try:
            # 检查同名博客是否已存在
            existing_blog = await blog_service.model.filter(
                title=blog_in.title, 
                user_id=blog_in.user_id,
                is_deleted=False
            ).first()
            if existing_blog:
                raise BusinessError(RESOURCE_ALREADY_EXISTS.format(resource="博客"), details="该博客标题已存在")
            
            new_blog = await blog_service.create(blog_in)
            return new_blog
        except Exception as e:
            raise BusinessError(RESOURCE_CREATE_FAILED.format(resource="博客"), details=f"创建博客失败 {str(e)}")

    async def update_blog_info(self, blog_id: int, obj_in: BlogUpdate, user_id: int) -> bool:
        """更新博客信息"""
        try:
            blog_obj = await blog_service.get_blog_by_user(blog_id, user_id)
            if not blog_obj:
                raise BusinessError(RESOURCE_NOT_FOUND.format(resource="博客"), details="博客不存在")
            await blog_service.update(blog_id, obj_in)
            return True
        except Exception as e:
            raise BusinessError(RESOURCE_UPDATE_FAILED.format(resource="博客"), details=f"更新博客失败 {str(e)}")

    async def increase_views(self, blog_id: int, user_id: int) -> Blog:
        """增加博客浏览量"""
        try:
            blog_obj = await blog_service.get_blog_by_user(blog_id, user_id)
            if not blog_obj:
                raise BusinessError(RESOURCE_NOT_FOUND.format(resource="博客"), details="博客不存在")
            blog_obj.views += 1
            await blog_obj.save()
            return blog_obj
        except Exception as e:
            raise BusinessError(OPERATION_FAILED.format(operation="增加浏览量"), details=f"增加浏览量失败 {str(e)}")

    async def toggle_like(self, blog_id: int, user_id: int) -> Blog:
        """点赞/取消点赞博客"""
        try:
            blog_obj = await blog_service.get_blog_by_user(blog_id, user_id)
            if not blog_obj:
                raise BusinessError(RESOURCE_NOT_FOUND.format(resource="博客"), details="博客不存在")
            blog_obj.likes = 1 if blog_obj.likes == 0 else 0
            await blog_obj.save()
            return blog_obj
        except Exception as e:
            raise BusinessError(OPERATION_FAILED.format(operation="点赞操作"), details=f"点赞操作失败 {str(e)}")

blog_controller = BlogController()